package com.yanqu.road.server.gameplayer.module.player;

import com.yanqu.road.entity.config.skin.SkinInfo;
import com.yanqu.road.entity.config.skinvolume.SkinEmbroideryConfigInfo;
import com.yanqu.road.entity.config.skinvolume.SkinVolumeConfigInfo;
import com.yanqu.road.entity.enums.eBigRankType;
import com.yanqu.road.entity.enums.eLogMoneyType;
import com.yanqu.road.entity.enums.eRankType;
import com.yanqu.road.entity.log.LogSkinVolumeEmbroideryFix;
import com.yanqu.road.entity.log.LogSkinVolumePiecesGet;
import com.yanqu.road.entity.player.*;
import com.yanqu.road.logic.bussiness.player.UserSkinVolumeBusiness;
import com.yanqu.road.logic.config.GameConfig;
import com.yanqu.road.pb.skinvolume.SkinVolumeProto;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.base.GeneralModule;
import com.yanqu.road.server.gameplayer.module.patrons.PatronsModule;
import com.yanqu.road.server.gameplayer.module.skin.SkinModule;
import com.yanqu.road.server.manger.config.SkinMgr;
import com.yanqu.road.server.manger.config.SkinVolumeMgr;
import com.yanqu.road.server.manger.log.LogMgr;
import com.yanqu.road.server.manger.rank.RankMgr;
import com.yanqu.road.server.protocol.ClientProtocol;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.utils.property.PropertyHelper;

import java.math.BigInteger;
import java.util.*;

/**
 * @author ：zfr
 * @date ：2021/4/26 21:37
 */
public class SkinVolumeModule extends GeneralModule {

    private UserSkinVolumeData skinVolumeData;

    private Map<Integer, UserSkinVolumeRewardData> rewardDataMap;

    public SkinVolumeModule(GamePlayer player) {
        super(player);
    }

    public UserSkinVolumeData getSkinVolumeData() {
        return skinVolumeData;
    }

    /**
     * 同步玩家数据
     */
    public void syncUserData() {
        SkinVolumeProto.SkinVolumeDataMsg.Builder syncMsg = SkinVolumeProto.SkinVolumeDataMsg.newBuilder();
        syncMsg.setEmbroideryMeter(skinVolumeData.getEmbroideryMeter());
        syncMsg.setPiecesCount((int) skinVolumeData.getPiecesCount());
        syncMsg.setUsedPiecesCount((int) skinVolumeData.getUsedPiecesCount());
        for (UserSkinVolumeRewardData rewardData : rewardDataMap.values()) {
            SkinVolumeProto.VolumeRewardTemp.Builder temp = SkinVolumeProto.VolumeRewardTemp.newBuilder();
            temp.setVolumeId(rewardData.getVolumeId());
            temp.addAllGetRewardIndex(rewardData.getGetRewardIndexList());
            syncMsg.addReward(temp);
        }
        player.sendPacket(ClientProtocol.U_SKIN_VOLUME_SYNC_USER_DATA, syncMsg);
    }

    @Override
    public void afterLogin() {
        syncUserData();
    }

    @Override
    public void loginSendMsg() {

    }

    /**
     * 是否达到解锁条件
     * @return
     */
    private boolean checkSystemOpen() {
        List<UserSkin> patronsSkinList = player.getModule(SkinModule.class).getSkinList();
        return patronsSkinList.size() >= GameConfig.UNLOCK_PATRONS_SKIN_VOLUME_NEED;
    }

    /**
     * 修复刺绣
     *
     * @return
     */
    public int fixNextMeterEmbroider(int meter) {
        //系统是否解锁
        if (!checkSystemOpen()) {
            return GameErrorCode.E_SKIN_VOLUME_NO_OPEN;
        }
        if (meter <= skinVolumeData.getEmbroideryMeter()) {
            return GameErrorCode.E_SKIN_VOLUME_METER_IS_UNLOCK;
        }
        //配置是否存在
        SkinEmbroideryConfigInfo skinEmbroideryConfigInfo = SkinVolumeMgr.getSkinEmbroideryConfigInfo(meter);
        if (skinEmbroideryConfigInfo == null) {
            return GameErrorCode.E_SKIN_VOLUME_CONFIG_NO_EXIST;
        }
        //残片数量是否足够解锁
        if (skinVolumeData.getPiecesCount() - skinVolumeData.getUsedPiecesCount() < skinEmbroideryConfigInfo.getFixNeed()) {
            return GameErrorCode.E_SKIN_VOLUME_PIECES_NO_ENOUGH;
        }

        skinVolumeData.setUsedPiecesCount(skinVolumeData.getUsedPiecesCount() + skinEmbroideryConfigInfo.getFixNeed());

        //修复
        skinVolumeData.setEmbroideryMeter(meter);
        //排行榜变更通知
        changeEmbroideryMeterRank();
        //通知属性变更
        syncEffectData();
        SkinVolumeProto.FixEmbroiderRespMsg.Builder respMsg = SkinVolumeProto.FixEmbroiderRespMsg.newBuilder();
        respMsg.setRet(0);
        respMsg.setEmbroideryMeter(skinVolumeData.getEmbroideryMeter());
        player.sendPacket(ClientProtocol.U_SKIN_VOLUME_FIX_EMBROIDER, respMsg);
        syncUserData();
        LogMgr.addLogSkinVolumeEmbroideryFix(new LogSkinVolumeEmbroideryFix(getUserId(), skinVolumeData.getPiecesCount(), skinVolumeData.getEmbroideryMeter(), new Date()));
        return 0;
    }

    public void syncEffectData() {
        BeautyModule beautyModule = player.getModule(BeautyModule.class);
        for (UserBeauty userBeauty : beautyModule.getBeautyMap().values()) {
            player.getModule(SkinModule.class).recaclBeautyAttr(userBeauty, false); //是否需要加入日志
        }
        beautyModule.syncUserBeauty(new ArrayList<>(beautyModule.getBeautyMap().values()), false);
        player.getModule(PatronsModule.class).onPatronsChange(null);


    }

    @Override
    public boolean loadData() {
        skinVolumeData = UserSkinVolumeBusiness.getSkinVolumeData(getUserId());
        rewardDataMap = UserSkinVolumeBusiness.getSkinVolumeRewardData(getUserId());
        if (skinVolumeData == null) {
            initSkinVolumeData();
        }
        updateSkinGetPiecesCount();
        return true;
    }

    /**
     * 同步更新残片数量
     */
    public void updatePiecesCount() {
        skinVolumeData.setPiecesCount(skinVolumeData.getSkinWayGet() + skinVolumeData.getOtherWayGet());
        syncUserData();
    }

    /**
     * 同步更新皮肤途径获得的残片数量
     */
    public void updateSkinGetPiecesCount() {
        long piecesCount = 0L;
        List<SkinVolumeCollect> skinVolumeCollects = getSkinVolumeCollectList();
        for (SkinVolumeCollect skinVolumeCollect : skinVolumeCollects) {
            piecesCount += skinVolumeCollect.getPiecesCount();
        }
        skinVolumeData.setSkinWayGet(piecesCount);
        updatePiecesCount();
    }

    /**
     * 通过其他途径增加的残片
     * @param count
     */
    public void addPieces(long count) {
        skinVolumeData.setOtherWayGet(skinVolumeData.getOtherWayGet() + count);
        LogMgr.addLogSkinVolumePiecesGet(new LogSkinVolumePiecesGet(getUserId(), 0, count, 3, new Date()));
        updatePiecesCount();
    }

    /**
     * 初始化数据
     */
    private void initSkinVolumeData() {
        skinVolumeData = new UserSkinVolumeData();
        skinVolumeData.setUserId(getUserId());
        skinVolumeData.setEmbroideryMeter(0);
        skinVolumeData.setPiecesCount(0L);
        skinVolumeData.setSkinWayGet(0L);
        skinVolumeData.setOtherWayGet(0L);
        skinVolumeData.setUsedPiecesCount(0L);
        skinVolumeData.setInsertOption();
    }

    /**
     * 排行榜变更
     */
    public void changeEmbroideryMeterRank() {
        try {
            RankMgr.changeUserRank(eBigRankType.Normal.getValue(), player.getUserId(), BigInteger.valueOf(skinVolumeData.getEmbroideryMeter()), eRankType.EmbroideryMeter.getValue(), "");
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    /**
     * 霓裳卷领奖
     * @param volumeId
     * @param index
     * @return
     */
    public int getReward(int volumeId, int index) {
        SkinVolumeConfigInfo skinVolumeConfigInfo = SkinVolumeMgr.getSkinVolumeConfigInfo(volumeId);
        if (skinVolumeConfigInfo == null) {
            return GameErrorCode.E_SKIN_VOLUME_CONFIG_NO_EXIST;
        }
        UserSkinVolumeRewardData rewardData = rewardDataMap.get(volumeId);
        if (rewardData == null) {
            initUserVolumeRewardData(volumeId);
            rewardData = rewardDataMap.get(volumeId);
        }
        if (rewardData.getGetRewardIndexList().contains(index)) {
            return GameErrorCode.E_SKIN_VOLUME_ALREADY_GET_REWARD;
        }
        List<UserSkin> patronsSkinList = player.getModule(SkinModule.class).getSkinList();
        int skinHas = 0;
        for (UserSkin userSkin : patronsSkinList) {
            if (skinVolumeConfigInfo.getSkinIdList().contains(userSkin.getSkinId())) {
                skinHas++;
            }
        }
        String[] rewardArr = skinVolumeConfigInfo.getRewardParam().split("\\|");
        String rewardStr = rewardArr[index - 1];
        String[] rewardSplit = rewardStr.split("-");
        if (skinHas < Integer.parseInt(rewardSplit[0])) {
            return GameErrorCode.E_SKIN_VOLUME_IS_UN_COMPLETE;
        }
        //可以领奖了
        rewardData.addGetRewardIndex(index);
        rewardData.setGetRewardTime(new Date());
        player.getModule(CurrencyModule.class).addCurrency(PropertyHelper.parseStringToProperty(rewardSplit[1]), eLogMoneyType.SkinVolume, eLogMoneyType.SkinVolumeGetReward);
        SkinVolumeProto.GetRewardRespMsg.Builder respMsg = SkinVolumeProto.GetRewardRespMsg.newBuilder();
        respMsg.setRet(0);
        respMsg.setReward(rewardSplit[1]);
        player.sendPacket(ClientProtocol.U_SKIN_VOLUME_GET_REWARD, respMsg);
        return 0;
    }

    /**
     * 初始化卷目奖励数据
     * @param volumeId
     */
    private void initUserVolumeRewardData(int volumeId) {
        UserSkinVolumeRewardData userSkinVolumeRewardData = new UserSkinVolumeRewardData();
        userSkinVolumeRewardData.setUserId(getUserId());
        userSkinVolumeRewardData.setVolumeId(volumeId);
        userSkinVolumeRewardData.setGetRewardIndexList(new ArrayList<>());
        userSkinVolumeRewardData.setGetRewardTime(new Date());
        userSkinVolumeRewardData.setInsertOption();
        rewardDataMap.put(volumeId, userSkinVolumeRewardData);
    }

    public void getPiecesCollectList() {
        List<SkinVolumeCollect> skinVolumeCollects = getSkinVolumeCollectList();
        skinVolumeCollects.sort(Comparator.comparing(SkinVolumeCollect::getPiecesCount).reversed());
        SkinVolumeProto.PiecesCollectListRespMsg.Builder respMsg = SkinVolumeProto.PiecesCollectListRespMsg.newBuilder();
        for (SkinVolumeCollect collect : skinVolumeCollects) {
            SkinVolumeProto.SkinPiecesCountTemp.Builder temp = SkinVolumeProto.SkinPiecesCountTemp.newBuilder();
            temp.setSkinId(collect.getSkinId());
            temp.setPiecesCount(collect.getPiecesCount());
            respMsg.addSkinPieces(temp);
        }
        player.sendPacket(ClientProtocol.U_SKIN_VOLUME_GET_PIECES_COLLECT_LIST, respMsg);
    }

    private List<SkinVolumeCollect> getSkinVolumeCollectList() {
        List<SkinVolumeCollect> skinVolumeCollects = new ArrayList<>();
        List<UserSkin> patronsSkinList = player.getModule(SkinModule.class).getSkinList();
        for (UserSkin userSkin : patronsSkinList) {
            SkinInfo skinInfo = SkinMgr.getSkinInfo(userSkin.getSkinId());
            if (skinInfo != null) {
                SkinVolumeCollect skinVolumeCollect = new SkinVolumeCollect();
                skinVolumeCollect.setSkinId(skinInfo.getSkinId());
                skinVolumeCollect.setPiecesCount(skinInfo.getUpgradeGet() * (userSkin.getLevel() - 1));
                skinVolumeCollects.add(skinVolumeCollect);
            }
        }
        return skinVolumeCollects;
    }



    @Override
    public boolean afterLoadData() {
        return false;
    }

    @Override
    public boolean saveData() {
        if (skinVolumeData.isInsertOption()) {
            UserSkinVolumeBusiness.addUserSkinVolumeData(skinVolumeData);
        } else if (skinVolumeData.isUpdateOption()) {
            UserSkinVolumeBusiness.updateUserSkinVolumeData(skinVolumeData);
        }

        for (UserSkinVolumeRewardData rewardData : rewardDataMap.values()) {
            if (rewardData.isInsertOption()) {
                UserSkinVolumeBusiness.addUserSkinVolumeRewardData(rewardData);
            } else if (rewardData.isUpdateOption()) {
                UserSkinVolumeBusiness.updateUserSkinVolumeRewardData(rewardData);
            }
        }
        return true;
    }
}
